package org.lab.tracecash.services;

import java.util.List;

import javax.inject.Inject;
import javax.inject.Provider;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;

import org.lab.tracecash.jpa.NamedQueries;
import org.lab.tracecash.model.Transaction;
import org.lab.tracecash.model.TransactionResolverRule;
import org.lab.tracecash.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TransactionRuleExecutor {

	private static final Logger LOG = LoggerFactory.getLogger(TransactionRuleExecutor.class);

	@Inject
	private Provider<EntityManager> entityManagerProvider;

	public void execute(User user) {
		if (user.getRules() == null || user.getRules().isEmpty()) {
			LOG.warn("No se han definido reglas");
		} else {
			EntityManager entityManager = entityManagerProvider.get();
			TypedQuery<Transaction> query = entityManager.createNamedQuery(NamedQueries.TRANSACTION_GET_BY_USER_UNCHECKED, Transaction.class);
			query.setParameter("ownerId", user.getId());
			List<Transaction> list = query.getResultList();
			LOG.debug("Aplicando reglas a %s operaciones", list.size());
			for (Transaction i : list) {
				executeRules(i, user);
			}
		}
	}

	private void executeRules(Transaction portfolioOperation, User user) {
		for (TransactionResolverRule i : user.getRules()) {
			String source = getSource(portfolioOperation, i);
			String exp = i.getExpression().toLowerCase();
			switch (i.getEvaluationType()) {
			case Contains:
				if (source != null && source.toLowerCase().contains(exp.toLowerCase())) {
					if (i.getSource() != null) {
						LOG.debug("Actualizando portfolio operation " + portfolioOperation + ": from = " + i.getSource());
						portfolioOperation.setFrom(i.getSource());
						entityManagerProvider.get().merge(portfolioOperation);
					}
					if (i.getTarget() != null) {
						LOG.debug("Actualizando portfolio operation " + portfolioOperation + ": to = " + i.getTarget());
						portfolioOperation.setTo(i.getTarget());
						entityManagerProvider.get().merge(portfolioOperation);
					}
				}
				break;
			default:
				LOG.warn("NOT IMPLEMENTED: " + i.getEvaluationType());
			}
		}
	}

	private String getSource(Transaction portfolioOperation, TransactionResolverRule i) {
		switch (i.getEvaluationSource()) {
		case ShortDesc:
			return portfolioOperation.getDesc();
		case LongDesc:
			return portfolioOperation.getLongDesc();
		}
		return null;
	}

}
